package baiduschPro;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.nifi.annotation.behavior.ReadsAttribute;
import org.apache.nifi.annotation.behavior.ReadsAttributes;
import org.apache.nifi.annotation.behavior.WritesAttribute;
import org.apache.nifi.annotation.behavior.WritesAttributes;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.SeeAlso;
import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.PropertyValue;
import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.AbstractProcessor;
import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.processor.ProcessSession;
import org.apache.nifi.processor.ProcessorInitializationContext;
import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.exception.ProcessException;
import org.apache.nifi.processor.io.OutputStreamCallback;
import org.apache.nifi.processor.util.StandardValidators;
import org.apache.nifi.stream.io.ByteArrayOutputStream;

import hylanda.common.FileWr;

@Tags({"codepage"})
@CapabilityDescription("识别html的码制，并同意转化为一种码制")
@SeeAlso({})
@ReadsAttributes({@ReadsAttribute(attribute="", description="")})
@WritesAttributes({@WritesAttribute(attribute="", description="")})
public class IdentCodePagetoOneCodePage extends AbstractProcessor {

	
	 public static final PropertyDescriptor FormatPageCode = new PropertyDescriptor
	            .Builder().name("FormatPageCode")
	            .displayName("统一码制")
	            .description("统一码制")
	            .required(true)
	            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
	            .build();
	 
/*	 public static final PropertyDescriptor IdentVar = new PropertyDescriptor
	            .Builder().name("IdentVar")
	            .displayName("识别码制附加正则串")
	            .description("识别码制附加正则串，内部有默认的识别规则，用户可以自己增加规则,用|连接多条")
	            .required(true)
	            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
	            .build();
	*/ 
	 public static final Relationship MY_RELATIONSHIPOK = new Relationship.Builder()
	            .name("gen success")
	            .description("success relationship")
	            .build();
	 
	  private List<PropertyDescriptor> descriptors;
	  private Set<Relationship> relationships;
	  
	  @Override
	 protected void init(final ProcessorInitializationContext context) {
	     final List<PropertyDescriptor> descriptors = new ArrayList<PropertyDescriptor>();
	     descriptors.add(FormatPageCode);
	    
	    
	     this.descriptors = Collections.unmodifiableList(descriptors);
	
	     final Set<Relationship> relationships = new HashSet<Relationship>();
	     relationships.add(MY_RELATIONSHIPOK);
	    
	     this.relationships = Collections.unmodifiableSet(relationships);
	 }
		
	 @Override
	 public Set<Relationship> getRelationships() {
	     return this.relationships;
	 }
	
	 @Override
	 public final List<PropertyDescriptor> getSupportedPropertyDescriptors() {
	     return descriptors;
	 }
		 
	
	public IdentCodePagetoOneCodePage() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
		// TODO Auto-generated method stub
		FlowFile flowFile = session.get();
	      if ( flowFile == null ) 
	      {
	      	
	      	System.out.println("flowfile is null");
	         return;
	      }
	      
	      //读取FlowFile
//        String content = "";
        byte[] by = null;
        InputStream in = session.read(flowFile);
        try {
			by = readStream(in);
//			content = new String(by,"UTF-8");
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			//return ;
		}
        
        PropertyValue fcodepagep = context.getProperty("FormatPageCode");
    	
    	String formatcodepage = fcodepagep.getValue();
    	
  //  	String result = "";
    	byte[] byok = null;
    	String identcode = IdentHtmlCodePage(by,formatcodepage);
    	if(formatcodepage.equalsIgnoreCase(identcode))
    		byok = by;
    	else	
    	{
			try {
				String result = new String(by,identcode);
				byok = result.getBytes(formatcodepage);
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	
  
 // FileWr.saveFile("e:\\test\\testzhuanma.html", byok);   
//  FileWr.saveFile("e:\\test\\testzhuanmagb.html", by);  
    	 //写flowfile
	     final byte[] bywrite = byok;
	     flowFile= session.write(flowFile, new OutputStreamCallback(){
	    		@Override
	    		public void process(OutputStream out) throws IOException{
	    			out.write(bywrite);
	    		}
	    	});
	     
	     session.transfer(flowFile,MY_RELATIONSHIPOK);
		
	}
	
	
	public String IdentHtmlCodePage(byte[] by,String formatcodepage)
	{
		String strCode= "";
		//鐢ㄦ鍒欏尮閰嶇爜鍒?
		String content="";
		try {
			content = new String(by,"UTF-8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String[] regs = {"<meta .*?; charset=(.*?)\".*?>","<meta .*?;charset=(.*?)\".*?>","<meta .*?;charset=(.*?);.*?>","<meta .*?; charset=(.*?);.*?>"};
		for(int i = 0; i < regs.length;i++)
		{
			String strReg = regs[i];
			strCode= paraseOnePatternOnestr(strReg,content);	
			if(strCode != null)
			{
				if(!strCode.isEmpty())
					break;;
			}
		}
		if(strCode == null)
			strCode = "";
		
		//杩涜缁熶竴
		//gbk  utf-8  gb2312   gb18030 UTF-8  
		if(strCode.equalsIgnoreCase("gbk"))
			strCode = "GBK";
		else if(strCode.equalsIgnoreCase("gb2312"))
			strCode = "GB2312";
		else if(strCode.equalsIgnoreCase("gb18030"))
			strCode = "GB18030";
		else if(strCode.equalsIgnoreCase("utf-8"))
			strCode = "UTF-8";
		else if(strCode.equalsIgnoreCase("utf8"))
			strCode = "UTF-8";
		else
		{
			System.out.println("parase code is "+strCode);
		}
		return strCode;
	}
	
	
	
    private String paraseOnePatternOnestr(String strReg,String strpage)
    {
    	String strRet = "";
    	Pattern p1 = Pattern.compile(strReg,Pattern.CASE_INSENSITIVE);
		Matcher m1=p1.matcher(strpage);
		boolean bFind = false;
		while(m1.find())
		{
			int nCnt = m1.groupCount();
			if(nCnt > 0)
			{
				strRet= m1.group(1);
				if(strRet == null)
					strRet = "";
				break;
			}
		}//while
		return strRet;
    }
    
	public static byte[] readStream(InputStream inStream) throws Exception {  
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();  
        byte[] buffer = new byte[1024];  
        int len = -1;  
        while ((len = inStream.read(buffer)) != -1) {  
            outSteam.write(buffer, 0, len);  
        }  
        outSteam.close();  
        inStream.close();  
        return outSteam.toByteArray();  
    } 
	

}
